package com.shanghaionstar.remote.presenter;

import android.content.Context;
import android.os.Message;
import android.support.v4.app.FragmentManager;

import com.onstar.cn.auth.userProfile.FeatureEnum;
import com.onstar.cn.common.exception.OnStarException;
import com.onstar.cn.common.util.CommonUtil;
import com.onstar.cn.common.util.Constants;
import com.onstar.cn.common.util.PreferencesUtls;
import com.onstar.cn.framework.mvp.base.IMVPScheduler;
import com.onstar.cn.framework.mvp.base.IMVPView;
import com.onstar.cn.framework.mvp.base.core.BasePresenter;
import com.onstar.cn.framework.utils.RxBus;
import com.onstar.cn.mag.enumtype.RemoteCommandsType;
import com.onstar.cn.rxconstants.RxConstants;
import com.onstar.cn.vehicle.entity.RequestStatus;
import com.onstar.cn.vehicle.response.AuthorizedSubscriberResponse;
import com.onstar.cn.vehicle.result.PollingResult;
import com.shanghaionstar.OnstarApplication;
import com.shanghaionstar.R;
import com.shanghaionstar.enumtype.FunctionNameFindId;
import com.shanghaionstar.iview.ILoginAndOutListener;
import com.shanghaionstar.pin.PinDialogFragment;
import com.shanghaionstar.remote.iview.IRemoteView;
import com.shanghaionstar.remote.model.CommandStatus;
import com.shanghaionstar.remote.model.RemoteModel;
import com.shanghaionstar.remote.service.RemoteService;
import com.shanghaionstar.remote.share.ShareRemoteService;
import com.shanghaionstar.report.bean.ReportReqParam;
import com.shanghaionstar.utils.ApplicationUtil;
import com.shanghaionstar.utils.BusinessUtil;
import com.shanghaionstar.utils.DateFormatUtil;
import com.shanghaionstar.utils.FinalConfigParams;
import com.shanghaionstar.utils.JoinMeConstants;
import com.shanghaionstar.utils.LoginUtil;

import org.json.JSONException;
import org.json.JSONObject;

import rx.Subscription;
import rx.functions.Action1;
import rx.functions.Func1;

/**
 * Created by 6335yz on 2016/6/25.
 */
public class RemotePresenter extends BasePresenter implements IRemotePresenter, ILoginAndOutListener {

    private RemoteService remoteService;
    private IRemoteView remoteView;
    private Subscription subscription;
    private Subscription pollingSubscription;
    private Subscription loginSubscription;
    private Subscription initAlertgSubscription;

    private ShareRemoteService shareRemoteService;



    protected PreferencesUtls preferences = PreferencesUtls.getInstance(OnstarApplication.getApplication());

    private Context context;

    public RemotePresenter(IMVPScheduler mvpScheduler, Context context) {
        super(mvpScheduler);
        remoteService = new RemoteService(context);
        this.context = context;
        super.setServiceProvider(remoteService);
        registPollingSub();
        /**
         * alert 30s init
         */
        initAlertParam();
    }

    private LoginUtil mLoginUtil;

    public void registLoginAndOutShowView() {
        mLoginUtil = new LoginUtil();
        mLoginUtil.loginAndOutShowView(OnstarApplication.getApplication(), this);
    }

    public void getAuthorizedStatus() {
        shareRemoteService = new ShareRemoteService(context);
        subscription = shareRemoteService.getSharingStatus().subscribeOn(mvpScheduler.backgroundThread()).observeOn(mvpScheduler.mainThread())
                .subscribe(new Action1<AuthorizedSubscriberResponse>() {
                    @Override
                    public void call(AuthorizedSubscriberResponse response) {
                        remoteView.showAuthorizeStatus(response);
                    }
                }, new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        if (throwable != null)
                           remoteView.onResponseError((OnStarException) throwable);
                    }
                });
    }

    private void initAlertParam() {
        initAlertgSubscription = remoteService.initAlertParams().subscribeOn(mvpScheduler.backgroundThread())
                .observeOn(mvpScheduler.mainThread()).subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        try {
                            ApplicationUtil.getInstance().setAlertDuration( Integer.parseInt(new JSONObject(s).getString("duration")));
                        } catch (JSONException e) {
                            ApplicationUtil.getInstance().setAlertDuration(ApplicationUtil.ALERT_DURATION_DEF);
                        }
                    }
                }, new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        ApplicationUtil.getInstance().setAlertDuration(ApplicationUtil.ALERT_DURATION_DEF);
                    }
                });
    }

    @Override
    public void setView(IMVPView view) {
        super.setView(view);
        remoteView = (IRemoteView) view;
    }

    /**
     * 操作入口
     *
     * @param remoteCommandsType
     */
    public void doCommand(RemoteCommandsType remoteCommandsType) {
        if (validateCommandType(remoteCommandsType)) {
            if (remoteView != null) {
                remoteView.onReponseSuccess(new RemoteModel.Builder()
                        .setRemoteCommandsType(remoteCommandsType)
                        .setAlertMsg(context.getString(getAlertDialogByType(remoteCommandsType.value())))
                        .setCommandStatus(CommandStatus.START).create());
            }
        }
    }

    private int getAlertDialogByType(String commandType) {
        int alertMsg;
        RemoteCommandsType remoteCommandsType = RemoteCommandsType.fromValue(commandType);
        if (remoteCommandsType != null) {
            switch (remoteCommandsType) {
                case COMMANDS_LOCK_DOOR:
                    alertMsg = R.string.remote_lock_dialog;
                    break;
                case COMMANDS_UNLOCK_DOOR:
                    alertMsg = R.string.remote_unlock_dialog;
                    break;
                case COMMANDS_START:
                    alertMsg = R.string.remote_start_dialog;
                    break;
                case COMMANDS_CANCEL_START:
                    alertMsg = R.string.remote_stop_dialog;
                    break;
                case COMMANDS_ALERT:
                    alertMsg = R.string.remote_alert_dialog;
                    break;
                default:
                    alertMsg = R.string.is_execute_control;
                    break;
            }
        } else {
            alertMsg = R.string.is_execute_control;
        }
        return alertMsg;
    }

    /**
     * 自动触发或弹pin码
     * call before start;
     *
     * @param
     */

    public void showPinOrNot(FragmentManager fragmentManager, RemoteModel remoteModel) {
        if (BusinessUtil.isAutoSendPin(remoteModel.getRemoteCommandsType(), context)) {
            remoteModel.setCommandStatus(CommandStatus.LOADING);
            if (remoteView != null) {
                remoteView.onReponseSuccess(remoteModel);
            }
            commandByType(remoteModel);
        } else {
            showPinDialogFragment(fragmentManager, remoteModel);
        }
    }

    private void showPinDialogFragment(FragmentManager fragmentManager, RemoteModel remoteModel) {
        PinDialogFragment pinDialogFragment = PinDialogFragment.newInstance(remoteModel.getRemoteCommandsType(), RxConstants.REMOTE_PAGE);
        pinDialogFragment.show(fragmentManager, "pin_dialog");
    }

    public static String getFunctionId(RemoteCommandsType remoteCommandsType) {
        String functionId = "";
        switch (remoteCommandsType) {
            case COMMANDS_LOCK_DOOR:
                functionId = FunctionNameFindId.Remote_DoorLock.getStringValue();
                break;
            case COMMANDS_UNLOCK_DOOR:
                functionId = FunctionNameFindId.Remote_DoorUnlock.getStringValue();
                break;
            case COMMANDS_CANCEL_START:
                functionId = FunctionNameFindId.Remote_CancelStart.getStringValue();
                break;
            case COMMANDS_START:
                functionId = FunctionNameFindId.Remote_Start.getStringValue();
                break;
            case COMMANDS_ALERT:
                functionId = FunctionNameFindId.Remote_HornsLights.getStringValue();
                break;
        }
        return functionId;
    }

    /**
     * pin码成功后回调
     *
     * @param remoteModel
     */
    public void commandByType(final RemoteModel remoteModel) {

        subscription = remoteService.commandByType(remoteModel)
                .subscribeOn(mvpScheduler.backgroundThread())
                .observeOn(mvpScheduler.mainThread())
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        if (remoteView != null) {
                            remoteView.showCommandLoading(true);
                        }
                    }
                }, new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        //里面抛出的Error信息
                        if (remoteView != null) {
                            BusinessUtil.sendReportByRequestParams(context, getFunctionId(remoteModel.getRemoteCommandsType()),
                                    ReportReqParam.getRemoteCommandReportParams(getFunctionId(remoteModel.getRemoteCommandsType()), false, throwable.getMessage()));
                            remoteView.onResponseError((OnStarException) throwable);
                        }
                    }
                });
    }

    public void unRegisterSubscriber() {
        if (subscription != null && !subscription.isUnsubscribed()) {
            subscription.unsubscribe();
        }
        if (pollingSubscription != null && !pollingSubscription.isUnsubscribed()) {
            pollingSubscription.unsubscribe();
        }
        if (loginSubscription != null && !loginSubscription.isUnsubscribed()) {
            loginSubscription.unsubscribe();
        }
        if (initAlertgSubscription != null && !initAlertgSubscription.isUnsubscribed()) {
            initAlertgSubscription.unsubscribe();
        }
        if (mLoginUtil != null)
            mLoginUtil.clearLoginOrOut();
    }

    private boolean isRemoteCommand(String sRemoteCommandsType) {
        RemoteCommandsType remoteCommandsType = RemoteCommandsType.fromValue(sRemoteCommandsType);
        if (remoteCommandsType == null) return false;
        return (remoteCommandsType == RemoteCommandsType.COMMANDS_LOCK_DOOR
                || remoteCommandsType == RemoteCommandsType.COMMANDS_UNLOCK_DOOR
                || remoteCommandsType == RemoteCommandsType.COMMANDS_ALERT
                || remoteCommandsType == RemoteCommandsType.COMMANDS_CANCEL_START
                || remoteCommandsType == RemoteCommandsType.COMMANDS_START);
    }

    /**
     * 处理Polling 返回结果
     */
    private void registPollingSub() {
        pollingSubscription = RxBus.getDefault()
                .toObserverable(Message.class)
                .subscribeOn(mvpScheduler.backgroundThread())
                .observeOn(mvpScheduler.mainThread())
                .filter(new Func1<Message, Boolean>() {
                    @Override
                    public Boolean call(Message message) {
                        boolean isRemote = message.what == RxConstants.REMOTE_ERROR;
                        isRemote |= message.what == RxConstants.REMOTE_POLLING;
                        isRemote |= message.what == RxConstants.REMOTE_POLLING_RESULT;
                        return isRemote;
                    }
                })
                .subscribe(new Action1<Message>() {
                    @Override
                    public void call(Message message) {
                        switch (message.what){

                        }
                    }
                });
//
//                .subscribe(new Action1<PollingResult>() {
//                    @Override
//                    public void call(PollingResult pollingResult) {
//                        if (RequestStatus.Success.getStringValue().equalsIgnoreCase(pollingResult.getRequestStatus())) {
//                            updateView(pollingResult);
//                        }
//                    }
//                });
    }

    private void updateView(PollingResult result) {
        RemoteCommandsType commandsType = RemoteCommandsType.fromValue(result.getRequestType());
        if (commandsType == null) return;
        StringBuffer commandResult = new StringBuffer();
        int commandId = 0;
        int resultId = 0;
        switch (commandsType) {
            case COMMANDS_UNLOCK_DOOR:
                commandId = R.string.remote_unlock;
                commandResult.append(context.getString(R.string.remote_unlock));
                break;
            case COMMANDS_LOCK_DOOR:
                commandId = R.string.remote_lock;
                commandResult.append(context.getString(R.string.remote_lock));
                break;
            case COMMANDS_START:
                commandId = R.string.remote_start;
                commandResult.append(context.getString(R.string.remote_start));
                break;
            case COMMANDS_CANCEL_START:
                commandId = R.string.remote_cancel_start;
                commandResult.append(context.getString(R.string.remote_cancel_start));
                break;
            case COMMANDS_ALERT:
                commandId = R.string.remote_alarm;
                commandResult.append(context.getString(R.string.remote_alarm));
                break;
        }
        if (RequestStatus.Success.getStringValue().equals(result.getRequestStatus())) {
            resultId = R.string.remote_command_success;
            commandResult.append(context.getString(R.string.remote_command_success));
        } else {
            resultId = R.string.remote_command_fail;
            commandResult.append(context.getString(R.string.remote_command_fail));
        }
        String formatCommandResult = "";
        if (!CommonUtil.isNull(result.getCompleteTime())) {
            formatCommandResult = DateFormatUtil.formatCST(result.getCompleteTime(), 8);
        }
        /**
         * 解决底部hint内容错乱问题
         */
//        preferences.putString(FinalConfigParams.LAST_COMMAND_TYPE + "_" + ApplicationUtil.getInstance().getVin();
        preferences.putString(FinalConfigParams.LAST_COMMAND_TYPE_NEW + "_" + ApplicationUtil.getInstance().getVin(),commandResult.toString());
        preferences.putString(FinalConfigParams.LAST_COMMAND_TIME_NEW + "_" + ApplicationUtil.getInstance().getVin(),formatCommandResult);
        if (remoteView != null) {
            remoteView.showCommandResult(true, commandResult.toString(), formatCommandResult);
        }
    }

    /**
     * 页面载入时，加载上次的操作
     */
    public void showBottomMsg(boolean isShow) {
        String commandResult = "";

        /**
         * 解决底部hint内容错乱问题
         */
        if (!CommonUtil.isNull(preferences.getString(FinalConfigParams.LAST_COMMAND_TYPE_NEW + "_" + ApplicationUtil.getInstance().getVin()))) {
            commandResult = preferences.getString(FinalConfigParams.LAST_COMMAND_TYPE_NEW + "_" + ApplicationUtil.getInstance().getVin());
        }
        String time = preferences.getString(FinalConfigParams.LAST_COMMAND_TIME_NEW + "_" + ApplicationUtil.getInstance().getVin());
        if (remoteView != null) {
            remoteView.showCommandResult(isShow, commandResult, time);
        }
    }

    private boolean validateCommandType(RemoteCommandsType remoteCommandsType) {
        return BusinessUtil.checkRemoteControl(context, Constants.ENTITLEMENT_M07REMOTE_CONTROL, 0, remoteView);
    }

    @Override
    public void onLogin() {
        if (BusinessUtil.isServiceFeature(FeatureEnum.START.value(), context)
                || JoinMeConstants.VISITOR.equalsIgnoreCase(ApplicationUtil.getInstance().getLoginRole())) {
            if (remoteView != null) {
                remoteView.showStartOrNot(true);
            }
        } else {
            if (remoteView != null) {
                remoteView.showStartOrNot(false);
            }
        }
        showBottomMsg(true);
    }

    @Override
    public void onLoginOut() {
        showBottomMsg(false);
    }
}
